package ar.uba.dc.tl.mylanga.semantic;

import ar.uba.dc.tl.mylanga.exception.SemanticException;
import ar.uba.dc.tl.mylanga.exception.SemanticExceptions;
import ar.uba.dc.tl.mylanga.node.PProgram;

import java.util.ArrayList;
import java.util.List;

public class SemanticAnalyzer {

	private PProgram program;
	private List<SemanticRule> semanticRules;

	public SemanticAnalyzer(PProgram program) {
		assert program != null;

		this.program = program;
		this.initializeSemanticRules();
	}

	public void check() {
		List<SemanticException> semanticExceptions = new ArrayList<>();

		for (SemanticRule semanticRule : this.semanticRules) {
			try {
				semanticRule.check();
			} catch (SemanticException semanticException) {
				semanticExceptions.add(semanticException);
			}
		}

		if (0 < semanticExceptions.size()) {
			throw new SemanticExceptions(semanticExceptions);
		}
	}

	private void initializeSemanticRules() {
		this.semanticRules = new ArrayList<>();

		this.semanticRules.add(new UndefinedVariableReferenceSemanticRule(this.program));
        this.semanticRules.add(new UndefinedFunctionReferenceSemanticRule((this.program)));
        this.semanticRules.add(new DuplicateFunctionRule(this.program));
        this.semanticRules.add(new FunctionMustReturnRule(this.program));
	}
}
